﻿// -----------------------------------------------------------------------
// <copyright file="ResponseBuilder.cs" company="Softserve">
// Made by VK
// </copyright>
// -----------------------------------------------------------------------
namespace WebServer.BusinessLogic
{
    using System;
    using System.Text;
    using WebServer.BusinessLogic.Logs;

    /// <summary>
    /// Is be able to provide raw data, needed for transfering it to the client
    /// </summary>
    public class ResponseBuilder
    {
        /// <summary>
        /// Response private containter with all necessary data for ResponseBuilder
        /// </summary>
        private Response response;

        /// <summary>
        /// Initializes a new instance of the <see cref="ResponseBuilder" /> class.
        /// </summary>
        /// <param name="response">response object</param>
        public ResponseBuilder(Response response)
        {
            this.response = response;
        }

        /// <summary>
        /// Gets response data
        /// </summary>
        /// <returns>Response object that was initializeb by constructor</returns>
        public Response Response
        {
            get { return this.response; }
        }

        /// <summary>
        /// Gets the raw bytes with all headers and body of response inside
        /// </summary>
        /// <returns>Bytes of raw data, null for error</returns>
        public byte[] GetResponseBytes()
        {
            // create Header
            var headerCreator = new ResponseHeaderCreator(this.response);
            headerCreator.Create();

            // get Header string value
            var header = headerCreator.ToString();

            // combine Header and Body
            byte[] result = this.CombineHeaderAndBody(header);

            // return combining result
            return result;
        }

        /// <summary>
        /// Combining header and body
        /// </summary>
        /// <param name="header">header line</param>
        /// <returns>byte array</returns>
        private byte[] CombineHeaderAndBody(string header)
        {
            // add CRLF to separate Header and Body
            header += "\r\n";

            // when we only have Header status, make Response.Data empty, not null so that combine is doesn't throw
            if (this.response.Data == null)
            {
                this.response.Data = new byte[0];
            }

            // get bytes of Header string
            var headerBytes = Encoding.UTF8.GetBytes(header);

            try
            {
                //// combine bytes of Header with bytes of Body
                var newResult = Helpers.ByteArraysCombineExtension.Combine(headerBytes, this.response.Data);
                return newResult;
            }
            catch (OutOfMemoryException)
            {
                //// too large data to combine
                Logger.Instance.Log(string.Format(
                                                "Not enough memory to combine array of size {0:0.##}KB",
                                                  this.response.Data.Length / 1024));
            }

            return null;
        }
    }
}
